package com.putao.album.fileupload;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.widget.Toast;

import com.loopj.android.http.RequestParams;
import com.putao.album.R;
import com.putao.album.eventbus.BasePostEvent;
import com.putao.album.util.CommonUtils;
import com.putao.album.util.HttpRequestUtil;
import com.putao.album.util.Loger;
import com.putao.album.util.NetUtil;
import com.putao.album.util.PuTaoConstants;
import com.putao.album.util.StringHelper;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;

import de.greenrobot.event.EventBus;

/**
 * Created by jidongdong on 15/5/8.
 */
public class FileUploadService extends Service {
    /**
     * 需要上传的文件队列
     */
    private Queue<FileInfo> mFilelist = new LinkedList<FileInfo>();

    /**
     * 标识是否暂停
     */
    private boolean mFlagPause = false;

    /**
     * 标识停止上传结束Service
     */
    private boolean mFlagStop = false;

    /**
     * 标识已经成功上传的个数
     */
    private int uploadedSuccessCount = 0;

    /**
     * 待上传文件总数
     */
    private int total = 0;

    /**
     * 上传文件的Token,每次start获取一次
     */
    private String uploadToken;

    private Context mContext;

    private boolean forceNoWifiUpload = false;

    public String getUploadToken() {
        return uploadToken;
    }

    public void setUploadToken(String uploadToken) {
        this.uploadToken = uploadToken;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mContext = this;
        if (intent != null) {
            Bundle bundle = intent.getExtras();
            String cmd = bundle.getString("command", "");
            forceNoWifiUpload = bundle.getBoolean("forceNoWifiUpload", false);
//        Loger.d("cmd---->" + cmd);
            exeCmd(bundle, cmd);
        }
        return START_STICKY;
    }

    /**
     * 执行上传任务命令
     *
     * @param bundle
     * @param cmd
     */
    void exeCmd(Bundle bundle, String cmd) {
        if (FileUploadState.START.equals(cmd)) {
            if (!mFilelist.isEmpty()) {
                mFilelist.clear();
                uploadedSuccessCount = 0;
            }
            mFilelist.addAll((java.util.Collection<? extends FileInfo>) bundle.getSerializable("filelist"));

            total = mFilelist.size();
            start();
        } else if (FileUploadState.PAUSE.equals(cmd)) {
            mFlagPause = true;
        } else if (FileUploadState.RESTART.equals(cmd)) {
            mFlagPause = false;
            start();
        } else if (FileUploadState.STOP.equals(cmd)) {
            mFlagStop = true;
            stopSelf();
        }

        //Loger.d("chen++++++++++exeCmd()++cmd:"+cmd);
    }

    private void start() {
        queryUploadToken();
    }

    private void startUploadFile() {
        if (mFilelist.isEmpty() || mFlagPause || mFlagStop) {
            if (uploadedSuccessCount > 0) {
                finishUploadThenPushMessage();
            }
            sendMsg(FileUploadState.FINISHED, 100);
            stopSelf();
            return;
        }

        if (CommonUtils.isOnlyWifiUploadOpen() && !forceNoWifiUpload) {
            if (!NetUtil.isWifiEnable(mContext)) {
                Toast.makeText(mContext, mContext.getString(R.string.only_wifi_upload), Toast.LENGTH_SHORT);
                sendMsg(FileUploadState.FINISHED, 100);
                stopSelf();
                return;
            }
        }
        //Loger.d("chen+++++forceNoWifiUpload=" + forceNoWifiUpload);

        sendMsg(FileUploadState.START, 0);
        FileInfo file = mFilelist.poll();
        if (file != null) {
            queryIsExist(file);
        }
    }

    private void queryUploadToken() {
        //http://api.camera.putao.io/policy/policy/getUploadToken?type=uploadPhotos
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("type", "uploadPhotos");
        params.put("baby_id", CommonUtils.getBabyId());
        HttpRequestUtil.doHttpGetRequest(mContext, PuTaoConstants.API_GET_TOKEN,
                new RequestParams(HttpRequestUtil.buildHttpRequestParams(params)), new HttpRequestUtil.RequestResponseListener() {
                    @Override
                    public void success(int statuscode, String response) {
                        if (!StringHelper.isEmpty(response)) {
                            try {
                                JSONObject json = new JSONObject(response);
                                String status = json.getString("status");
                                if (status.equals(HttpRequestUtil.ResponseCode.api_code_200)) {
                                    uploadToken = json.getString("uploadToken");
                                    setUploadToken(uploadToken);
                                    startUploadFile();
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }

                    @Override
                    public void failed(int statuscode, String response) {
                        Loger.d("statuscode:" + statuscode + ",response:::" + response);
                        sendMsg(FileUploadState.FINISHED, 100);
                    }
                });
    }

    private void queryIsExist(final FileInfo info) {
        File file = new File(info.getFilePath());
        if (file.exists()) {
            String takeTime = new SimpleDateFormat(mContext.getResources().getString(R.string.time_format_ymd_hms))
                    .format(file.lastModified());
            String hash = CommonUtils.getHashByFile(file);
            String headHash = CommonUtils.getFileHeadHash(file);
            info.setTakeTime(takeTime);
            info.setHash(hash);
            info.setHeadHash(headHash);
        } else {
            startUploadFile();
            return;
        }

        HashMap<String, String> params = new HashMap<String, String>();
        params.put("sha1", info.getHash());
        HttpRequestUtil.doHttpPostRequest(mContext, PuTaoConstants.API_UPLOAD_CHECK,
                new RequestParams(HttpRequestUtil.buildHttpRequestParams(params)), new HttpRequestUtil.RequestResponseListener() {
                    @Override
                    public void success(int statuscode, String response) {
                        try {
                            JSONObject json = new JSONObject(response);
                            String status = json.getString("status");
                            JSONObject data = json.getJSONObject("data");
                            if (StringHelper.isEmpty(data.getString("msg"))) {
                                //{"status":"200","data":{"msg":""}}
                                queryNewFileToServer(info);
                            } else {
                                //{"status":"200","data":{"msg":"214026329c5cfc3ccd9fd836effb3ff1a7912a52"}}
                                queryExistFileToServer(info);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void failed(int statuscode, String response) {
                        Loger.i("queryIsExist:failed statuscode:" + statuscode + "response" + response);
                        sendMsg(FileUploadState.UPLOADING, 100);
                        startUploadFile();
                    }
                });
    }

    private void finishUploadThenPushMessage() {
        //http://api.camera.putao.com/baby/baby/uploadAfterCallBack    POST  uid/ baby_id

        HashMap<String, String> params = new HashMap<String, String>();
        params.put("baby_id", CommonUtils.getBabyId());
        HttpRequestUtil.doHttpPostRequest(mContext, PuTaoConstants.API_POST_UPLOAD_AFTER_CALLBACK,
                new RequestParams(HttpRequestUtil.buildHttpRequestParams(params)),
                new HttpRequestUtil.RequestResponseListener() {
                    @Override
                    public void success(int statuscode, String response) {
                        //无回复内容
                    }

                    @Override
                    public void failed(int statuscode, String response) {
                    }
                });
    }

    private void queryExistFileToServer(final FileInfo fileInfo) {
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("uploadToken", getUploadToken());
        params.put("filename", fileInfo.getFilePath());
        params.put("sha1", fileInfo.getHash());
        params.put("baby_id", fileInfo.getBabyId());
        params.put("shoot_time", fileInfo.getTakeTime());
        HttpRequestUtil.doHttpPostRequest(mContext, PuTaoConstants.API_UPLOAD_UPLOAD_NOFILEUUPLOAD,
                new RequestParams(HttpRequestUtil.buildHttpRequestParams(params)), new HttpRequestUtil.RequestResponseListener() {
                    @Override
                    public void success(int statuscode, String response) {
                        try {
                            //{"data":{"photo_id":"2750"},"status":"200"}
                            if (HttpRequestUtil.ResponseCode.api_code_200.equals(HttpRequestUtil.getResponseCode(response))) {

                                uploadedSuccessCount++;

                                JSONObject data = HttpRequestUtil.getResponseData(response);
                                String photoID = data.optString("photo_id");

                                fileInfo.setStatus(1L);
                                fileInfo.setPhotoId(photoID);
                                saveUploadInfoToDB(fileInfo);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            sendMsg(FileUploadState.UPLOADING, 100);
                            //继续传
                            startUploadFile();
                        }
                    }

                    @Override
                    public void failed(int statuscode, String response) {
                        sendMsg(FileUploadState.UPLOADING, 100);
                        startUploadFile();
                    }
                });
    }

    private void queryNewFileToServer(final FileInfo fileInfo) {
        RequestParams params = null;
        try {
            params = new RequestParams(HttpRequestUtil.buildHttpRequestParams(new HashMap()));
            params.put("file", new File(fileInfo.getFilePath()));
            params.put("uploadToken", getUploadToken());
            params.put("filename", fileInfo.getFilePath());
            //业务参数
            params.put("baby_id", fileInfo.getBabyId());
            params.put("shoot_time", fileInfo.getTakeTime());
        } catch (Exception e) {
            e.printStackTrace();
        }

        HttpRequestUtil.doFileUploadRequest(mContext, PuTaoConstants.API_UPLOAD_UPLOAD_UPLOAD, params,
                new HttpRequestUtil.FileUploadRequestResponseListener() {
                    long lastTime = System.currentTimeMillis();

                    @Override
                    public void success(int statuscode, String response) {

                        try {
                            //{"data":{"photo_id":"2750"},"status":"200"}
                            if (HttpRequestUtil.ResponseCode.api_code_200.equals(HttpRequestUtil.getResponseCode(response))) {

                                uploadedSuccessCount++;

                                JSONObject data = HttpRequestUtil.getResponseData(response);
                                String photoID = data.optString("photo_id");

                                fileInfo.setStatus(1L);
                                fileInfo.setPhotoId(photoID);
                                saveUploadInfoToDB(fileInfo);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            sendMsg(FileUploadState.UPLOADING, 100);
                            //继续传
                            startUploadFile();
                        }
                    }

                    @Override
                    public void failed(int statuscode, String response) {

                        sendMsg(FileUploadState.UPLOADING, 100);
                        startUploadFile();
                    }

                    @Override
                    public void onprogress(int bytesWritten, int totalSize) {

                        long currentTime = System.currentTimeMillis();
                        if (currentTime - lastTime > 50) {
                            lastTime = currentTime;
                            int progress = bytesWritten * 100 / totalSize;
                            if (0 <= progress && progress <= 100) {
                                sendMsg(FileUploadState.UPLOADING, progress);
                            }
                        }
                    }
                });
    }

    /**
     * 保存上传记录信息到数据库
     *
     * @param info
     */

    private void saveUploadInfoToDB(FileInfo info) {
        FileUploadDBHelper.getInstance().update(info);
    }

    /**
     * 发送上传过程消息
     *
     * @param status
     * @param progress
     */
    private void sendMsg(String status, int progress) {
        Bundle bundle = new Bundle();
        int curindex = total - mFilelist.size();
        //STATUS_FINISH or  STATUS_UPLOADING
        bundle.putString("status", status);
        //正在上传第curindex个文件
        bundle.putInt("curindex", curindex);
        //当前文件的上传进度
        bundle.putInt("progress", progress);
        //已经上传成功的文件数据
        bundle.putInt("success", uploadedSuccessCount);
        //总共需要上传的文件数目
        bundle.putInt("total", total);


//        mFilelist.poll()
//        File file = new File(info.getFilePath());
//        if (file.exists()) {
//            String takeTime = new SimpleDateFormat(mContext.getResources().getString(R.string.time_format_ymd_hms))
//                    .format(file.lastModified());
//            String hash = CommonUtils.getHashByFile(file);
//            String headHash = CommonUtils.getFileHeadHash(file);
//            info.setTakeTime(takeTime);
//            info.setHash(hash);
//            info.setHeadHash(headHash);

        EventBus.getDefault().post(new BasePostEvent(PuTaoConstants.EVENTBUS_UPLOAD_PHOTOS, bundle));

        Loger.d("FileUploadService+++++++sendMsg():" + "status=" + status + ",curindex=" + curindex + ",progress=" + progress
                + "%,success=" + uploadedSuccessCount + ",total=" + total);
    }
}
